home *** CD-ROM | disk | FTP | other *** search
- /* This STANDALONE variable doesn't work to build a Standalone LZHUF executable. */
- #undef STANDALONE
- /*
- ************************************************************
- lzhuf.c
- written by Haruyasu Yoshizaki 11/20/1988
- some minor changes 4/6/1989
- comments translated by Haruhiko Okumura 4/7/1989
- ************************************************************
- */
- #ifndef MSDOS
- #include "ctype.h"
- #endif
- #ifndef STANDALONE
- #include "global.h"
- #include <time.h>
- #include "forward.h"
- #else
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define LZHUF 1
- #define mallocw malloc
- #endif
-
- #if defined(LZHUF) || defined(FBBCMP)
- #ifndef MSDOS
- #include "session.h"
- #endif
-
- #undef DEBUG
- #undef DEBUG2
-
- #if !defined(_lint)
- static char rcsid[] OPTIONAL = "$Id: lzhuf.c,v 1.16 1997/07/31 00:44:20 root Exp root $";
- #endif
-
- #if defined(CATALOG) && !defined(STANDALONE)
- #include "catalog.h"
-
- #define CAT lzhuf_catalog
-
- #define ErrorEncode __STR(0)
- #define lostremote __STR(1)
- #define ErrorDecode __STR(2)
- #define Erroropening __STR(3)
- #define ENCODEratio __STR(4)
- #define DECODEratio __STR(5)
-
- #else /* CATALOG */
- static const char ErrorEncode[] = "FWDCMP: Error from Encode() rc = %d";
- static const char lostremote[] = "FBBFWD: Lost the remote connection in recv_yapp()";
- static const char ErrorDecode[] = "FWDCMP: Error from Decode() rc = %d";
- static const char Erroropening[] = "FBBFWD: Error opening %s in %s\n";
- static const char ENCODEratio[] = "FWDCMP: ENCODE: In: %-8ld Out: %-8ld (%ld%%)\n";
- static const char DECODEratio[] = "FWDCMP: DECODE: In: %-8ld Out: %-8ld (%ld%%)\n";
-
- #endif /* CATALOG */
-
-
- static const char Encodestr[] = "Encode()";
- static const char Decodestr[] = "Decode()";
-
- #ifdef STANDALONE
- #undef free
- #undef malloc
- #define tcmdprintf printf
- int FBBtrace = 1;
- #endif
-
-
-
- static void
- AllocDataBuffers (struct fwd *f)
- {
- f->lzhuf = mallocw (sizeof (struct lzhufstruct));
- #if 0
- f->tmpBuffer = mallocw (260);
- #endif
-
- f->lzhuf->data_type = 0; /* 0 means not allocated yet. */
- f->lzhuf->data = mallocw (sizeof (struct lzhufdata));
-
- if (f->lzhuf->data != NULLLZHUFDATA)
- f->lzhuf->data_type = 2; /* 2 means big buffer + lower memory. */
-
- if (f->lzhuf->data_type == 0) {
- f->lzhuf->data_type = 1; /* 1 means small buffers + lower memory. */
- f->lzhuf->dad = mallocw ((N + 1) * sizeof (int));
- f->lzhuf->lson = mallocw ((N + 1) * sizeof (int));
- f->lzhuf->rson = mallocw ((N + 257) * sizeof (int));
- f->lzhuf->text_buf = mallocw ((N + F - 1) * sizeof (unsigned char));
- f->lzhuf->freq = mallocw ((T + 1) * sizeof (unsigned));
- f->lzhuf->prnt = mallocw ((T + N_CHAR) * sizeof (int));
- f->lzhuf->son = mallocw ((T) * sizeof (int));
- } else {
- /* point pointers to correct spot in large buffer. */
- f->lzhuf->dad = f->lzhuf->data->dad;
- f->lzhuf->rson = f->lzhuf->data->rson;
- f->lzhuf->lson = f->lzhuf->data->lson;
- f->lzhuf->text_buf = f->lzhuf->data->text_buf;
- f->lzhuf->freq = f->lzhuf->data->freq;
- f->lzhuf->prnt = f->lzhuf->data->prnt;
- f->lzhuf->son = f->lzhuf->data->son;
- }
- f->lzhuf->codesize = 0;
- f->lzhuf->getbuf = 0;
- f->lzhuf->getlen = 0;
- f->lzhuf->putbuf = 0;
- f->lzhuf->putlen = 0;
- f->lzhuf->code = 0;
- f->lzhuf->len = 0;
- }
-
-
-
- static void
- FreeDataBuffers (struct fwd *f)
- {
- #if 0
- free (f->tmpBuffer);
- #endif
-
- if (f->lzhuf->data_type == 1) {
- /* Free lower memory blocks. */
- free (f->lzhuf->dad);
- free (f->lzhuf->lson);
- free (f->lzhuf->rson);
- free (f->lzhuf->text_buf);
- free (f->lzhuf->freq);
- free (f->lzhuf->prnt);
- free (f->lzhuf->son);
- } else if (f->lzhuf->data_type == 2) {
- /* Free lower memory block. */
- free (f->lzhuf->data);
- }
- free (f->lzhuf);
- f->lzhuf = NULLLZHUFSTRUCT;
- }
-
-
-
- static int Encode (int, char *, char *, struct lzhufstruct *, int trace);
- static int Decode (int, char *, char *, struct lzhufstruct *, int addex, int trace);
- static int GetBit (struct lzhufstruct *);
- static unsigned short GetByte (struct lzhufstruct *);
- static void Putcode (struct lzhufstruct *, int, unsigned);
- static void EncodeEnd (struct lzhufstruct *);
- static int DecodeChar (struct lzhufstruct *);
-
-
- static void InitTree (struct lzhufstruct *);
- static void InsertNode (struct lzhufstruct *, int);
- static void StartHuff (struct lzhufstruct *);
- static void reconst (struct lzhufstruct *);
- static void lzhuf_update (struct lzhufstruct *, int);
- static void EncodeChar (struct lzhufstruct *, unsigned);
- static void EncodePosition (struct lzhufstruct *, unsigned);
- static int DecodePosition (struct lzhufstruct *);
- static void DeleteNode (struct lzhufstruct *, int);
- static int recvbuf (int, char *, unsigned);
-
- /********** LZSS compression **********/
-
-
-
- static void
- InitTree (struct lzhufstruct *lzhuf)
- { /* initialize trees */
- int i;
-
- for (i = N + 1; i <= N + 256; i++)
- lzhuf->rson[i] = NIL; /* root */
- for (i = 0; i < N; i++)
- lzhuf->dad[i] = NIL; /* node */
- }
-
-
-
- static void
- InsertNode (struct lzhufstruct *lzhuf, int r)
- { /* insert to tree */
- int i, p, cmp;
- unsigned char *key;
- unsigned c;
-
- cmp = 1;
- key = &lzhuf->text_buf[r];
- p = N + 1 + key[0];
- lzhuf->rson[r] = lzhuf->lson[r] = NIL;
- lzhuf->match_length = 0;
- for (;;) {
- if (cmp >= 0) {
- if (lzhuf->rson[p] != NIL)
- p = lzhuf->rson[p];
- else {
- lzhuf->rson[p] = r;
- lzhuf->dad[r] = p;
- return;
- }
- } else {
- if (lzhuf->lson[p] != NIL)
- p = lzhuf->lson[p];
- else {
- lzhuf->lson[p] = r;
- lzhuf->dad[r] = p;
- return;
- }
- }
- for (i = 1; i < F; i++)
- if ((cmp = key[i] - lzhuf->text_buf[p + i]) != 0)
- break;
- if (i > THRESHOLD) {
- if (i > lzhuf->match_length) {
- lzhuf->match_position = ((r - p) & (N - 1)) - 1;
- if ((lzhuf->match_length = i) >= F)
- break;
- }
- if (i == lzhuf->match_length) {
- if ((c = ((r - p) & (N - 1)) - 1) < (unsigned) lzhuf->match_position)
- lzhuf->match_position = (int) c;
- }
- }
- }
- lzhuf->dad[r] = lzhuf->dad[p];
- lzhuf->lson[r] = lzhuf->lson[p];
- lzhuf->rson[r] = lzhuf->rson[p];
- lzhuf->dad[lzhuf->lson[p]] = r;
- lzhuf->dad[lzhuf->rson[p]] = r;
- if (lzhuf->rson[lzhuf->dad[p]] == p)
- lzhuf->rson[lzhuf->dad[p]] = r;
- else
- lzhuf->lson[lzhuf->dad[p]] = r;
- lzhuf->dad[p] = NIL; /* remove p */
- }
-
-
-
- static void
- DeleteNode (struct lzhufstruct *lzhuf, int p)
- { /* remove from tree */
- int q;
-
- if (lzhuf->dad[p] == NIL)
- return; /* not registered */
- if (lzhuf->rson[p] == NIL)
- q = lzhuf->lson[p];
- else if (lzhuf->lson[p] == NIL)
- q = lzhuf->rson[p];
- else {
- q = lzhuf->lson[p];
- if (lzhuf->rson[q] != NIL) {
- do {
- q = lzhuf->rson[q];
- } while (lzhuf->rson[q] != NIL);
- lzhuf->rson[lzhuf->dad[q]] = lzhuf->lson[q];
- lzhuf->dad[lzhuf->lson[q]] = lzhuf->dad[q];
- lzhuf->lson[q] = lzhuf->lson[p];
- lzhuf->dad[lzhuf->lson[p]] = q;
- }
- lzhuf->rson[q] = lzhuf->rson[p];
- lzhuf->dad[lzhuf->rson[p]] = q;
- }
- lzhuf->dad[q] = lzhuf->dad[p];
- if (lzhuf->rson[lzhuf->dad[p]] == p)
- lzhuf->rson[lzhuf->dad[p]] = q;
- else
- lzhuf->lson[lzhuf->dad[p]] = q;
- lzhuf->dad[p] = NIL;
- }
-
-
-
- /* Huffman coding */
-
- /* table for encoding and decoding the upper 6 bits of position */
-
- /* for encoding */
- #define MAX_P_LEN 64
- static uint8 p_len[MAX_P_LEN] =
- {
- 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
- };
-
- static uint8 p_code[MAX_P_LEN] =
- {
- 0x00, 0x20, 0x30, 0x40, 0x50, 0x58, 0x60, 0x68,
- 0x70, 0x78, 0x80, 0x88, 0x90, 0x94, 0x98, 0x9C,
- 0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC,
- 0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE,
- 0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE,
- 0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE,
- 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
- 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
- };
-
- /* for decoding */
- #define MAX_D_LEN 256
- static uint8 d_code[MAX_D_LEN] =
- {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
- 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
- 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
- 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
- 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
- 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
- 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
- 0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B,
- 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F,
- 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23,
- 0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
- 0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B,
- 0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
- };
-
- static uint8 d_len[MAX_D_LEN] =
- {
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- };
-
-
-
- static int
- GetBit (struct lzhufstruct *lzhuf)
- { /* get one bit */
- register unsigned i;
- register unsigned dx = lzhuf->getbuf;
- register unsigned char glen = lzhuf->getlen;
-
- while (glen <= 8) {
- i = (unsigned) getc (lzhuf->iFile);
- if ((int) i < 0)
- i = 0;
- dx |= i << (8 - glen);
- glen += 8;
- }
- lzhuf->getbuf = dx << 1;
- lzhuf->getlen = glen - 1;
- return (dx & 0x8000) ? 1 : 0;
- }
-
-
-
- static unsigned short
- GetByte (struct lzhufstruct *lzhuf)
- { /* get one byte */
- register unsigned i;
- register unsigned dx = lzhuf->getbuf;
- register unsigned char glen = lzhuf->getlen;
-
- while (glen <= 8) {
- i = (unsigned) getc (lzhuf->iFile);
- if ((int) i < 0)
- i = 0;
- dx |= i << (8 - glen);
- glen += 8;
- }
- lzhuf->getbuf = dx << 8;
- lzhuf->getlen = glen - 8;
- return (dx >> 8) & 0xff;
- }
-
-
-
- static void
- Putcode (struct lzhufstruct *lzhuf, int l, unsigned c)
- { /* output c bits of code */
- lzhuf->putbuf |= c >> lzhuf->putlen;
- if ((lzhuf->putlen += uchar (l)) >= 8) {
- if (putc (lzhuf->putbuf >> 8, lzhuf->oFile) == EOF)
- return;
-
- if ((lzhuf->putlen -= 8) >= 8) {
- if (putc ((int) lzhuf->putbuf, lzhuf->oFile) == EOF)
- return;
-
- lzhuf->codesize += 2;
- lzhuf->putlen -= 8;
- lzhuf->putbuf = c << (l - lzhuf->putlen);
- } else {
- lzhuf->putbuf <<= 8;
- lzhuf->codesize++;
- }
- }
- }
-
-
-
- /* initialization of tree */
-
- static void
- StartHuff (struct lzhufstruct *lzhuf)
- {
- int i, j;
-
- for (i = 0; i < N_CHAR; i++) {
- lzhuf->freq[i] = 1;
- lzhuf->son[i] = i + T;
- lzhuf->prnt[i + T] = i;
- }
- i = 0;
- j = N_CHAR;
- while (j <= R) {
- lzhuf->freq[j] = lzhuf->freq[i] + lzhuf->freq[i + 1];
- lzhuf->son[j] = i;
- lzhuf->prnt[i] = lzhuf->prnt[i + 1] = j;
- i += 2;
- j++;
- }
- lzhuf->freq[T] = 0xffff;
- lzhuf->prnt[R] = 0;
- lzhuf->putlen = lzhuf->getlen = 0;
- lzhuf->putbuf = lzhuf->getbuf = 0;
- }
-
-
-
- /* reconstruction of tree */
- static void
- reconst (struct lzhufstruct *lzhuf)
- {
- int i, j, k;
- unsigned first;
-
- /* collect leaf nodes in the first half of the table */
- /* and replace the freq by (freq + 1) / 2. */
- j = 0;
- for (i = 0; i < T; i++) {
- if (lzhuf->son[i] >= T) {
- lzhuf->freq[j] = (lzhuf->freq[i] + 1) / 2;
- lzhuf->son[j] = lzhuf->son[i];
- j++;
- }
- }
- /* begin constructing tree by connecting sons */
- for (i = 0, j = N_CHAR; j < T; i += 2, j++) {
- k = i + 1;
- first = lzhuf->freq[j] = lzhuf->freq[i] + lzhuf->freq[k];
- for (k = j - 1; first < lzhuf->freq[k]; k--)
- ;
- k++;
- {
- register unsigned *p, *e;
-
- for (p = &lzhuf->freq[j], e = &lzhuf->freq[k]; p > e; p--)
- p[0] = p[-1];
- lzhuf->freq[k] = first;
- }
- {
- register int *p, *e;
-
- for (p = &lzhuf->son[j], e = &lzhuf->son[k]; p > e; p--)
- p[0] = p[-1];
- lzhuf->son[k] = i;
- }
- }
- /* connect prnt */
- for (i = 0; i < T; i++) {
- if ((k = lzhuf->son[i]) >= T)
- lzhuf->prnt[k] = i;
- else
- lzhuf->prnt[k] = lzhuf->prnt[k + 1] = i;
- }
- }
-
-
-
- /* increment frequency of given code by one, and update tree */
- void
- lzhuf_update (struct lzhufstruct *lzhuf, int c)
- {
- int i, j, k, l;
-
- if (lzhuf->freq[R] == MAX_FREQ)
- reconst (lzhuf);
-
- c = lzhuf->prnt[c + T];
- do {
- k = (int) ++lzhuf->freq[c];
-
- /* if the order is disturbed, exchange nodes */
- if ((unsigned) k > lzhuf->freq[l = c + 1]) {
- while ((unsigned) k > lzhuf->freq[++l])
- ;
- l--;
- lzhuf->freq[c] = lzhuf->freq[l];
- lzhuf->freq[l] = (unsigned int) k;
-
- i = lzhuf->son[c];
- lzhuf->prnt[i] = l;
- if (i < T)
- lzhuf->prnt[i + 1] = l;
-
- j = lzhuf->son[l];
- lzhuf->son[l] = i;
-
- lzhuf->prnt[j] = c;
- if (j < T)
- lzhuf->prnt[j + 1] = c;
- lzhuf->son[c] = j;
-
- c = l;
- }
- } while ((c = lzhuf->prnt[c]) != 0); /* repeat up to root */
- }
-
-
-
- static void
- EncodeChar (struct lzhufstruct *lzhuf, unsigned c)
- {
- unsigned i;
- int j, k;
-
- i = 0;
- j = 0;
- k = lzhuf->prnt[c + T];
-
- /* travel from leaf to root */
- do {
- i >>= 1;
-
- /* if node's address is odd-numbered, choose bigger brother node */
- if (k & 1)
- i += 0x8000;
-
- j++;
- } while ((k = lzhuf->prnt[k]) != R);
- Putcode (lzhuf, j, i);
- lzhuf->code = i;
- lzhuf->len = (unsigned int) j;
- lzhuf_update (lzhuf, (int) c);
- }
-
-
-
- static void
- EncodePosition (struct lzhufstruct *lzhuf, unsigned c)
- {
- unsigned i;
-
- /* output upper 6 bits by table lookup */
- i = c >> 6;
- #ifdef DEBUG
- if (i >= MAX_P_LEN)
- tcmdprintf ("Ah....FYI...you've just exceded the MAX_P_LEN variable ( %d ) with %d\n", MAX_P_LEN, i);
- #endif
- Putcode (lzhuf, p_len[i], (unsigned) p_code[i] << 8);
-
- /* output lower 6 bits verbatim */
- Putcode (lzhuf, 6, (c & 0x3f) << 10);
- }
-
-
-
- static void
- EncodeEnd (struct lzhufstruct *lzhuf)
- {
- if (lzhuf->putlen) {
- if (putc (lzhuf->putbuf >> 8, lzhuf->oFile) == EOF)
- return;
- lzhuf->codesize++;
- }
- }
-
-
-
- static int
- DecodeChar (struct lzhufstruct *lzhuf)
- {
- unsigned c;
-
- c = (unsigned) lzhuf->son[R];
-
- /* travel from root to leaf, */
- /* choosing the smaller child node (son[]) if the read bit is 0, */
- /* the bigger (son[]+1} if 1 */
- while (c < T) {
- c += (unsigned) GetBit (lzhuf);
- c = (unsigned) lzhuf->son[c];
- }
- c -= T;
- lzhuf_update (lzhuf, (int) c);
- return (int) c;
- }
-
-
-
- static int
- DecodePosition (struct lzhufstruct *lzhuf)
- {
- unsigned j, c;
- unsigned short i;
-
- /* recover upper 6 bits from table */
- i = GetByte (lzhuf);
- #ifdef DEBUG
- if (i >= MAX_D_LEN)
- tcmdprintf ("Ah....FYI...you've just exceded the MAX_D_LEN variable ( %u ) with %u\n", MAX_D_LEN, i);
- #endif
- c = (unsigned) d_code[i] << 6;
- j = d_len[i];
-
- /* read lower 6 bits verbatim */
- j -= 2;
- while (j--)
- i = (int16) ((i << 1) + GetBit (lzhuf));
-
- return (int) (c | (i & 0x3f));
- }
-
-
-
- /* compression */
- static int
- Encode (int usock OPTIONAL, char *txtFileName, char *binFileName, struct lzhufstruct *lzhuf, int trace)
- {
- int i, c, len, r, s, last_match_length;
- unsigned long int filesize = 0;
-
- #ifdef DEBUG
- tcmdprintf ("Encoding %s into %s\n", txtFileName, binFileName);
- #endif
-
- /* Open input and output files. */
- if ((lzhuf->iFile = fopen (txtFileName, "rb")) == NULLFILE) {
- if (trace)
- tcmdprintf (Erroropening, txtFileName, Encodestr);
- return 0;
- }
- if ((lzhuf->oFile = fopen (binFileName, "wb")) == NULLFILE) {
- if (trace)
- tcmdprintf (Erroropening, binFileName, Encodestr);
- return 0;
- }
- fseek (lzhuf->iFile, 0L, 2);
- filesize = (unsigned long) ftell (lzhuf->iFile);
- if (filesize == 0)
- return 0;
- /* output size of text */
- if (fwrite (&filesize, sizeof (filesize), 1, lzhuf->oFile) < 1)
- return 0;
- rewind (lzhuf->iFile);
-
- lzhuf->iFileSize = filesize;
- filesize = 0; /* rewind and re-read */
-
- StartHuff (lzhuf);
- InitTree (lzhuf);
-
- s = 0;
- r = N - F;
- for (i = s; i < r; i++)
- lzhuf->text_buf[i] = ' ';
- for (len = 0; len < F && (c = getc (lzhuf->iFile)) != EOF; len++)
- lzhuf->text_buf[r + len] = uchar (c);
- filesize = (unsigned long) len;
- for (i = 1; i <= F; i++)
- InsertNode (lzhuf, r - i);
- InsertNode (lzhuf, r);
- do {
- kwait (NULL);
- if (lzhuf->match_length > len)
- lzhuf->match_length = len;
- if (lzhuf->match_length <= THRESHOLD) {
- lzhuf->match_length = 1;
- EncodeChar (lzhuf, lzhuf->text_buf[r]);
- } else {
- EncodeChar (lzhuf, (unsigned) (255 - THRESHOLD + lzhuf->match_length));
- EncodePosition (lzhuf, (unsigned) lzhuf->match_position);
- }
- last_match_length = lzhuf->match_length;
- for (i = 0; i < last_match_length && (c = getc (lzhuf->iFile)) != EOF; i++) {
- DeleteNode (lzhuf, s);
- lzhuf->text_buf[s] = uchar (c);
- if (s < F - 1)
- lzhuf->text_buf[s + N] = uchar (c);
- s = (s + 1) & (N - 1);
- r = (r + 1) & (N - 1);
- InsertNode (lzhuf, r);
- }
- while (i++ < last_match_length) {
- DeleteNode (lzhuf, s);
- s = (s + 1) & (N - 1);
- r = (r + 1) & (N - 1);
- if (--len)
- InsertNode (lzhuf, r);
- }
- } while (len > 0);
- EncodeEnd (lzhuf);
- (void) fclose (lzhuf->iFile);
- (void) fclose (lzhuf->oFile);
-
- if (lzhuf->iFileSize == 0)
- lzhuf->iFileSize = 1;
- if (trace)
- tcmdprintf (ENCODEratio, lzhuf->iFileSize, lzhuf->codesize,
- (100 - ((lzhuf->codesize * 100) / (long) lzhuf->iFileSize)));
- return 1;
- }
-
-
-
- static int
- Decode (int usock OPTIONAL, char *iFile, char *oFile, struct lzhufstruct *lzhuf, int addex, int trace)
- {
- int i = 0;
- int j = 0;
- int k = 0;
- int r = 0;
- int c = 0;
- unsigned long int count = 0;
- long int filesize = 0;
-
- #ifdef DEBUG
- tcmdprintf ("Decoding %s into %s\n", iFile, oFile);
- #endif
-
- /* Open input and output files. */
- if ((lzhuf->iFile = fopen (iFile, "rb")) == NULLFILE) {
- if (trace)
- tcmdprintf (Erroropening, iFile, Decodestr);
- return 0;
- }
- if ((lzhuf->oFile = fopen (oFile, "wb")) == NULLFILE) {
- if (trace)
- tcmdprintf (Erroropening, oFile, Decodestr);
- return 0;
- }
- fseek (lzhuf->iFile, 0L, 2);
- filesize = ftell (lzhuf->iFile);
- if (filesize == 0)
- return 0;
- lzhuf->iFileSize = (unsigned long) filesize;
- rewind (lzhuf->iFile);
-
- if (fread (&filesize, sizeof (filesize), 1, lzhuf->iFile) < 1)
- return 0;
- if (filesize == 0)
- return 0;
-
- StartHuff (lzhuf);
- for (i = 0; i < N - F; i++)
- lzhuf->text_buf[i] = ' ';
-
- r = N - F;
- for (count = 0; count < (unsigned long) filesize;) {
- kwait (NULL);
- c = DecodeChar (lzhuf);
- if (c < 256) {
- if (putc (c, lzhuf->oFile) == EOF)
- return 0;
-
- lzhuf->text_buf[r++] = uchar (c);
- r &= (N - 1);
- count++;
- } else {
- i = (r - DecodePosition (lzhuf) - 1) & (N - 1);
- j = c - 255 + THRESHOLD;
- for (k = 0; k < j; k++) {
- c = lzhuf->text_buf[(i + k) & (N - 1)];
- if (putc (c, lzhuf->oFile) == EOF)
- return 0;
-
- lzhuf->text_buf[r++] = uchar (c);
- r &= (N - 1);
- count++;
- }
- }
- }
-
- #ifndef STANDALONE
- if (addex)
- /* This terminates a note. */
- fputs ("\n/EX\n", lzhuf->oFile);
- #endif
-
- (void) fclose (lzhuf->iFile);
- (void) fclose (lzhuf->oFile);
-
- if (count == 0)
- count = 1;
- if (trace)
- tcmdprintf (DECODEratio, lzhuf->iFileSize, count,
- (100 - ((lzhuf->iFileSize * 100) / count)));
- return 1;
- }
-
-
-
- #ifndef STANDALONE
- int
- send_yapp (struct fwd *f, char *txtFileName, char *subj)
- {
- #define SLEN 79 /* Maximum subject */
- int oldmode; /* Socket Mode holder. */
- char *buffer; /* buffer data. */
- int buffer_len; /* buffer Length. */
- int x; /* misc counter. */
- int cnt; /* misc counter. */
- int rc;
- int Error;
- int usock;
- short b_checksum; /* buffer checksum. */
- short f_checksum; /* file checksum. */
- FILE *binFile;
- char binFileName[80];
- #ifdef DEBUG2
- FILE *debug;
- #endif
-
- /* Debug info. */
- #ifdef DEBUG2
- if (((debug = fopen (tmpnam (NULL), "wb")) == NULLFILE)) {
- printf ("Error opening input file.\n");
- return 0;
- }
- #endif
-
- /* User socket */
- usock = f->m->user;
-
- /* Encode code. */
- (void) tmpnam (binFileName);
-
- Error = FALSE;
-
- kwait (NULL);
- AllocDataBuffers (f);
- rc = Encode (usock, txtFileName, binFileName, f->lzhuf, FBBtrace);
- FreeDataBuffers (f);
- kwait (NULL);
- if (!rc) {
- if (FBBtrace)
- tcmdprintf (ErrorEncode, rc);
- log (f->m->user, ErrorEncode, rc);
- Error = TRUE;
- unlink (binFileName); /* just in case */
- }
- unlink (txtFileName);
-
- if (Error)
- return 0;
-
- /* open the compressed data file. */
- /* Now... we're going to read from the file and close it when we exit. */
-
- /* Open the input file. */
- binFile = fopen (binFileName, "rb");
- if (binFile == NULLFILE)
- return 0;
-
- /* Debug info. */
- #ifdef DEBUG
- tcmdprintf ("we opened %s for input.\n", f->oFile);
- #endif
-
- /* Grab some space. Largest YAPP packet is 250+ bytes. */
- f->tmpBuffer = mallocw (260);
- buffer = f->tmpBuffer;
-
- /* Set the socket to Binary mode since we'll be sending Binary data. */
- oldmode = sockmode (usock, SOCK_BINARY);
-
- /* Send the subject buffer
- The buffer is setup as follows:
- Pos Data
- 1 SOH
- 2 Length of entire buffer ( 8 bytes + strlen(subject) )
- 3 Null terminated Subject string.
- x Null terminated '0' string.
- */
-
- /* Make sure that the subject strlen() is equal to or less than SLEN */
- x = (int) strlen (subj);
- if (x >= SLEN) {
- x = SLEN;
- subj[SLEN] = '\0';
- }
- /* length of subject + NULL + length of " 0" + NULL */
- buffer_len = x + 1 + 6 + 1;
-
- /* Build the buffer. */
- buffer[0] = SOH; /* buffer_Type */
- buffer[1] = (char) buffer_len; /* buffer_Len */
- strcpy (&buffer[2], subj); /* Subject info. */
- strcpy (&buffer[x + 3], " 0"); /* Always 0 for FBB Messages. */
-
- /* Now we can send it. */
- /* buffer_len + 2 ( for the first two bytes. */
- (void) usputbuf (usock, (unsigned char *) buffer, buffer_len + 2);
- #ifdef DEBUG2
- fwrite (buffer, buffer_len + 2, 1, debug);
- #endif
-
- /* Send the data buffers. */
- f_checksum = 0;
- /* fill buffer with data. Bytes 0 and 1 are reserved. */
- while ((x = (int) fread (&buffer[2], 1, 250, binFile)) > 0) {
- /* prepare the buffer. */
- buffer[0] = STX;/* buffer_Type */
- buffer[1] = (char) x; /* buffer_Len */
-
- b_checksum = 0;
- for (cnt = 0; cnt < x; cnt++)
- b_checksum += buffer[2 + cnt]; /* buffer checksum. */
-
- #if 0 /* must be for FBB 4.15C ?? */
- buffer[x + 2] = ((-b_checksum) & 0xff); /* Store b_checksum. */
- #endif
-
- /* and send it. */
- (void) usputbuf (usock, (unsigned char *) buffer, (x + 2));
- #ifdef DEBUG2
- fwrite (buffer, x + 2, 1, debug);
- #endif
-
- f_checksum += b_checksum;
- } /* endwhile */
-
- /* Send the EOT */
- /* Prepare the buffer. */
- buffer[0] = EOT; /* buffer_Type */
- buffer[1] = (char) ((-f_checksum) & 0xff); /* Checksum. */
-
- /* and send it. */
- (void) usputbuf (usock, (unsigned char *) buffer, 2);
- #ifdef DEBUG2
- fwrite (buffer, 2, 1, debug);
- #endif
-
- /* Terminate. */
- (void) fclose (binFile);
-
- /* Delete binFileName */
- unlink (binFileName);
-
- #ifdef DEBUG2
- (void) fclose (debug);
- #endif
- free (f->tmpBuffer);
- /* Set the socket back to it's orginal mode. */
- (void) sockmode (usock, oldmode);
- return 1;
- }
-
-
- int
- recv_yapp (struct fwd *f)
- {
- int recvcnt;
- int packet_type;
- unsigned int packet_size;
- char packet_data[258];
- int GetSubject;
- int NoteDone;
- int NoteError;
- unsigned int rx_checksumctr;
- unsigned int rx_checksum;
- int rc;
- int oldmode; /* Socket Mode holder. */
- FILE *iFile = NULLFILE;
- int usock;
-
- /* User socket */
- usock = f->m->user;
-
- /* Set the socket to Binary mode since we'll be sending Binary data. */
- oldmode = sockmode (usock, SOCK_BINARY);
-
- GetSubject = TRUE;
- NoteDone = FALSE;
- NoteError = FALSE;
- rx_checksum = 0;
-
- while (!NoteDone) {
- /* Get the data packets. */
- packet_type = recvchar (usock);
-
- if (GetSubject) {
- if (packet_type != SOH) {
- FBBerror (0, usock, f->m);
- NoteDone = NoteError = TRUE;
- continue;
- }
- } else if ((packet_type != STX) && (packet_type != EOT)) {
- /* Get the packet size. */
- packet_size = (unsigned int) recvchar (usock);
- FBBerror (3, usock, f->m);
- NoteDone = NoteError = TRUE;
- continue;
- }
- /* Get the packet size. */
- packet_size = (unsigned int) recvchar (usock);
- if (!packet_size)
- packet_size = 256; /* 0x00 always means 256 */
-
- if (packet_type == SOH) {
- /* This is the subject. Reset the flag so we don't */
- /* come here again. */
- GetSubject = FALSE;
-
- /* Open the output file. */
- if (iFile == NULLFILE) /* shouldn't be needed, but just in case */
- if ((iFile = fopen (f->iFile, "wb")) == NULLFILE)
- return 0;
-
- /* This is a subject packet (with the offset hiding behind it). */
- recvcnt = recvbuf (usock, &packet_data[0], packet_size + 1);
- /* we have now read the subject (which we'll use) and the
- offset (which we are assuming to be zero), which we ignore */
- if (recvcnt == -1) {
- if (FBBtrace) {
- tcmdprintf (lostremote);
- tcmdprintf ("\n");
- }
- log (f->m->user, lostremote);
- /* We've lost the connection.... */
- NoteDone = NoteError = TRUE;
- } else
- f->m->subject = strdup (packet_data);
- }
- /* endif */
- else if (packet_type == STX) {
- /* Validate the packet */
- /* and write it to the file. */
- recvcnt = recvbuf (usock, &packet_data[0], packet_size + 1);
- if (recvcnt == -1) {
- if (FBBtrace) {
- tcmdprintf (lostremote);
- tcmdprintf ("\n");
- }
- log (f->m->user, lostremote);
- /* We've lost the connection.... */
- NoteDone = NoteError = TRUE;
- } else {
- /* Write to disk */
- if (iFile)
- fwrite (packet_data, (unsigned int) recvcnt, 1, iFile);
-
- /* add the data to the rx_checksum count. */
- for (rx_checksumctr = 0; rx_checksumctr < packet_size; rx_checksumctr++)
- rx_checksum += (unsigned char) packet_data[rx_checksumctr];
- }
- }
- /* endif */
- else if (packet_type == EOT) {
- /* Close the file. */
- /* Validate the Checksum. */
- /* erase the file if Checksum fails.*/
- /* Get ready to read next message. */
-
- if (packet_size == 256)
- packet_size = 0;
- if (packet_size != (unsigned int) ((-(int) rx_checksum) & 0xff)) {
- NoteDone = NoteError = TRUE;
- usputs (usock, "*** CHECKSUM ERROR\n");
- if (FBBtrace)
- tcmdprintf ("FBBCMP: Checksum Error in message data\n");
- log (f->m->user, "Checksum Error in message data");
- } else if (FBBtrace)
- tcmdprintf ("FBBCMP: YAPP Message Checksum verified\n");
- /* Close the data file. */
- if (iFile)
- (void) fclose (iFile);
- iFile = NULLFILE;
-
- /* We're done with this message. Return. */
- NoteDone = TRUE;
- } /* endif */
- } /* End while !NoteDone */
-
- if (!NoteError) {
- kwait (NULL);
- AllocDataBuffers (f);
- rc = Decode (usock, f->iFile, f->oFile, f->lzhuf, 1, FBBtrace);
- FreeDataBuffers (f);
- kwait (NULL);
- if (!rc) {
- if (FBBtrace)
- tcmdprintf (ErrorDecode, rc);
- log (f->m->user, ErrorDecode, rc);
- NoteError = TRUE;
- }
- }
- if (iFile != NULLFILE)
- (void) fclose (iFile);
-
- /* delete compressed file. */
- unlink (f->iFile);
-
- /* Set the socket back to it's orginal mode. */
- (void) sockmode (usock, oldmode);
- if (!NoteError)
- return 1;
- else
- return 0;
- }
-
-
-
- /* Receive a buffer from a socket, returning # chars read.
- */
- static int
- recvbuf (int s, char *buf, unsigned len)
- {
- int c;
- int cnt = 0;
-
- while (len-- > 1) {
- if ((c = recvchar (s)) == EOF) {
- cnt = -1;
- break;
- }
- if (buf != NULLCHAR)
- *buf++ = (char) c;
- cnt++;
- }
- return cnt;
- }
- #endif
-
-
-
- #ifdef XFWD
- int
- send_lzhuf (struct fwd *f, char *txtFileName)
- {
- int oldmode; /* Socket Mode holder. */
- int rc, c;
- int Error;
- int usock;
- FILE *binFile;
- char binFileName[80];
- int16 newchecksum = 0;
-
- /* User socket */
- usock = f->m->user;
-
- /* Encode code. */
- (void) tmpnam (binFileName);
-
- Error = FALSE;
-
- kwait (NULL);
- AllocDataBuffers (f);
- rc = Encode (usock, txtFileName, binFileName, f->lzhuf, Xtrace);
- FreeDataBuffers (f);
- kwait (NULL);
- if (!rc) {
- if (Xtrace)
- tcmdprintf (ErrorEncode, rc);
- log (f->m->user, ErrorEncode, rc);
- Error = TRUE;
- unlink (binFileName); /* just in case */
- }
- unlink (txtFileName);
-
- if (Error) {
- tprintf ("SS 0\n");
- return 0;
- }
- /* open the compressed data file. */
- /* Now... we're going to read from the file and close it when we exit. */
-
- kwait (NULL);
-
- /* Open the input file. */
- binFile = fopen (binFileName, "rb");
- if (binFile == NULLFILE)
- return 0;
-
- kwait (NULL);
-
- /* Calculate checksum */
- while ((c = fgetc (binFile)) != EOF)
- newchecksum += (int16) c;
-
- rewind (binFile);
- kwait (NULL);
-
- tprintf ("SS %ld %u\n", filelength (fileno (binFile)), newchecksum);
- if (Xtrace)
- tcmdprintf ("XFWD: Sending 'SS %ld %u'\n", filelength (fileno (binFile)), newchecksum);
-
- /* Set the socket to Binary mode since we'll be sending Binary data. */
- oldmode = sockmode (usock, SOCK_BINARY);
-
- while ((c = fgetc (binFile)) != EOF)
- tputc (uchar (c));
-
- /* Terminate. */
- (void) fclose (binFile);
-
- /* Delete binFileName */
- unlink (binFileName);
-
- /* Set the socket back to it's orginal mode. */
- (void) sockmode (usock, oldmode);
- return 1;
- }
-
-
-
- int
- recv_lzhuf (struct fwd *f, int msgsize, int16 * newchecksum)
- {
- int c;
- int Error = FALSE;
- int rc;
- int oldmode; /* Socket Mode holder. */
- FILE *iFile = NULLFILE;
- int usock;
-
- *newchecksum = 0;
-
- /* User socket */
- usock = f->m->user;
-
- /* Set the socket to Binary mode since we'll be sending Binary data. */
- oldmode = sockmode (usock, SOCK_BINARY);
-
- iFile = fopen (f->iFile, "wb");
- if (iFile == NULLFILE)
- return 0;
-
- while (msgsize--) {
- /* Get the data. */
- c = recvchar (usock);
- *newchecksum += (int16) c;
- fputc (c, iFile);
- }
-
- (void) fclose (iFile);
- AllocDataBuffers (f);
- rc = Decode (usock, f->iFile, f->oFile, f->lzhuf, 0, Xtrace);
- FreeDataBuffers (f);
- if (!rc) {
- if (Xtrace)
- tcmdprintf (ErrorDecode, rc);
- log (f->m->user, ErrorDecode, rc);
- Error = TRUE;
- }
- /* delete compressed file. */
- unlink (f->iFile);
-
- kwait (NULL);
-
- /* Set the socket back to it's orginal mode. */
- (void) sockmode (usock, oldmode);
- if (!Error)
- return 1;
- else
- return 0;
- }
- #endif
-
-
-
- #ifdef STANDALONE
- int
- kwait (volatile void *event)
- {
- }
-
-
-
- void
- main (argc, argv, envp)
- int argc;
- char *argv[];
- char *envp[];
- {
- struct fwd f;
-
- AllocDataBuffers (&f);
- if (argv[1][0] == 'd')
- Decode (0, argv[2], argv[3], f.lzhuf, 0, FBBtrace);
- else
- Encode (0, argv[2], argv[3], f.lzhuf, FBBtrace);
- }
- #endif
- #endif
-